package org.paradigmshift.timelapse.ui

import scala.swing.event.ButtonClicked
import scala.swing.event.SelectionChanged
import scala.swing.Action
import scala.swing.BoxPanel
import scala.swing.Button
import scala.swing.Dialog
import scala.swing.FlowPanel
import scala.swing.GridBagPanel
import scala.swing.Label
import scala.swing.Orientation
import scala.swing.Swing
import scala.swing.TabbedPane
import org.paradigmshift.timelapse.rest.JsonRestConnection
import org.paradigmshift.timelapse.TimeLapsePreferences

class PreferencesDialog extends Dialog {
  title = "Preferences"
  modal = true
  
  private val cancelButton = new Button( "Cancel" )
  private val saveButton = new Button( "Save" )
  
  private def addListeners( input:PreferencesInput ) {
    if ( OSValidator.isMac ) {
      input.listenTo( input )
      input.reactions += {
        case ButtonClicked( `input` ) => input.save
      }
    }
    else {
      listenTo( saveButton, cancelButton )
      reactions += {
        case ButtonClicked( `saveButton` ) => input.save
        case ButtonClicked( `cancelButton` ) => input.init
      }
    }
  }
  
  private val searchInputs = Map(
    new Label( "Use JQL:" ) -> new PreferencesCheckBox( TimeLapsePreferences.setUseJql _, TimeLapsePreferences.getUseJql _ ),
    new Label( "Default search:" ) -> new PreferencesTextField( TimeLapsePreferences.setDefaultSearch _, TimeLapsePreferences.getDefaultSearch _ ) { columns = 15 },
    new Label( "Result set size:" ) -> new PreferencesTextField( (size:String) => TimeLapsePreferences.setResultSetSize( size.toInt ), TimeLapsePreferences.getResultSetSize.toString _ ) { columns = 3 }
  )
  
  private val connectionInputs = Map(
    new Label( "Scheme:" ) -> new PreferencesTextField( TimeLapsePreferences.setScheme _, TimeLapsePreferences.getScheme _ ) { columns = 6 },
    new Label( "Host:" ) -> new PreferencesTextField( TimeLapsePreferences.setHost _, TimeLapsePreferences.getHost _ ) { columns = 15 },
    new Label( "Port:" ) -> new PreferencesTextField( (port:String) => TimeLapsePreferences.setPort( port.toInt ), TimeLapsePreferences.getPort.toString _ ) { columns = 5 },
    new Label( "Username:" ) -> new PreferencesTextField( TimeLapsePreferences.setUsername _, TimeLapsePreferences.getUsername _ ) { columns = 10 }
  )
  
  private val searchForm = new GridBagPanel {
    border = Swing.EmptyBorder( 15 )
    
    private val c = new Constraints
    c.fill = GridBagPanel.Fill.None
    
    searchInputs.foldLeft(0)( (i, t) => {
      addListeners( t._2 )
      c.anchor = GridBagPanel.Anchor.East
      c.grid = ( 0, i )
      layout( t._1 ) = c
      
      c.anchor = GridBagPanel.Anchor.West
      c.grid = ( 1, i )
      layout( t._2 ) = c
      i + 1
    })
  }
  
  private val connectionForm = new GridBagPanel {
    border = Swing.EmptyBorder( 15 )
    
    private val c = new Constraints
    c.fill = GridBagPanel.Fill.None
    
    connectionInputs.foldLeft(0)( (i, t) => {
      addListeners( t._2 )
      c.anchor = GridBagPanel.Anchor.East
      c.grid = ( 0, i )
      layout( t._1 ) = c
      
      c.anchor = GridBagPanel.Anchor.West
      c.grid = ( 1, i )
      layout( t._2 ) = c
      i + 1
    })
    
    c.anchor = GridBagPanel.Anchor.West
    c.grid = ( 1, connectionInputs.size )
    layout( new Button {
      action = Action( "Clear Authentication" ) {
        JsonRestConnection.setAuth( TimeLapsePreferences.getUsername, "" )
      }
    }) = c
  }
  
  private val tabPane = new TabbedPane {
    pages += new TabbedPane.Page( "Search", searchForm )
    pages += new TabbedPane.Page( "Connection", connectionForm )
  }
  
  contents = new BoxPanel( Orientation.Vertical ) {
    border = Swing.EmptyBorder( 10 )
    contents += tabPane
    
    if ( !OSValidator.isMac ) {
      contents += new FlowPanel( FlowPanel.Alignment.Right )( cancelButton, saveButton )
    }
  }
  
  listenTo( tabPane.selection, cancelButton, saveButton )
  reactions += {
    case SelectionChanged( selection ) => pack
    case ButtonClicked( b ) => close
  }
  
  centerOnScreen
  resizable = false
  pack
}